package geoapi

import (
	"encoding/json"
	"io/ioutil"
	"net"
	"net/http"
	"strings"
)

// IPGeo 统一结构
type IPGeo struct {
	Status      string
	Query       string
	CountryName string
	CountryCode string
	StateProv   string
	City        string
	Location    string
	Isp         string
}

// getApiData 请求某个 api 获取 ip 地址信息
func getApiData(uri string) (data []byte, err error) {
	resp, err := http.Get(uri)
	if err != nil {
		return
	}
	defer resp.Body.Close()
	data, err = ioutil.ReadAll(resp.Body)
	return
}

type location struct {
	ccode     string
	cname1    string
	cname2    string
	phoneCode string
}

var locationDB = []location{}

// 通过查询获取国家地区代码
func getCountryCode(countryName string) (countryCode string) {
	// 查库, 查请求接口获取国家地区代码
	// 从本地查找

	if len(locationDB) > 0 {
		countryCode = queryCCode(countryName)
	} else if data, err := ioutil.ReadFile("countryCode.csv"); err == nil {
		for _, line := range strings.Split(string(data), "\n") {
			l := strings.Split(line, ",")
			if len(l) == 4 {
				locationDB = append(locationDB, location{l[0], l[1], l[2], l[3]})
			}
		}
		countryCode = queryCCode(countryName)
	}
	return
}

func queryCCode(s string) string {
	t := strings.TrimSpace(s)
	for _, loc := range locationDB {
		for {
			if strings.ReplaceAll(loc.cname1, s, "") != loc.cname1 {
				return loc.ccode
			}
			s = s[0 : len(s)-3]
			if len(s) <= 3 {
				break
			}
		}
		s = t
	}
	return ""
}

type youdaoResp struct {
	ErrorCode       int `json:"errorCode"`
	TranslateResult [][]struct {
		Src string `json:"src"`
		Tgt string `json:"tgt"`
	} `json:"translateResult"`
}

// 中英文转换
func zh2en(s string) (d string) {
	d = s
	uri := `http://fanyi.youdao.com/translate?&doctype=json&type=ZH_CN2EN &i=` + s
	data, err := getApiData(uri)
	if err != nil {
		return
	}
	var t youdaoResp
	err = json.Unmarshal(data, &t)
	if err != nil {
		return
	}
	if t.ErrorCode != 0 {
		return
	}
	if t.TranslateResult[0][0].Tgt == "" {
		return
	}
	d = t.TranslateResult[0][0].Tgt
	return
}

// CheckHost 检查 host 是否有效的 IP 地址或可解析的域名
func CheckHost(host string) (ip string, err error) {
	if net.ParseIP(host) != nil {
		ip = host
		return
	}
	addrs, err := net.LookupHost(host)
	if err != nil {
		return
	}
	ip = addrs[0]
	return
}

// GeoQuery 统一查询接口
func GeoQuery(host, chid string) (ig IPGeo, err error) {
	switch chid {
	case "1":
		ig, err = GeoBaidu(host)
	case "2":
		ig, err = GeoJuhe(host)
	case "3":
		ig, err = GeoIPAPI(host)
	case "4":
		ig, err = GeoDBIP(host)
	default:
		ig, err = GeoSogou(host)
	}
	return
}
